
***Replication do-file: Adapt or perish
***Author: Marc van de Wardt
***E-mail: M.vdWardt@uvt.nl
***Date: 27-2-2019
***Notes: to obtain model fit indices after firthlogit analyses, you need to install the user-written package firthfit

ssc install firthfit

log using "YOUR LOCATION\manuscript other tables and figures.smcl", replace

set more off

use "YOUR LOCATION\replication data.dta", clear

gen yline=0

***Description of variables used for analyses presented in manuscript
label var country "Country name"
label var ccode "Country code"
label var elec_year "Election year (Parlgov.org)"
label var elec_month "Election month (Parlgov.org)"
label var party_id "Party identifier (Parlgov.org)"
label var party_name_english "Party name (Parlgov.org)"
label var index "Election counter"
label var pss "Party system saturation t (Based on residuals of Model 2, Table 2 of van de Wardt(2017)"
label var nicheness "Nicheness of party program t (Formula after Meyer and Wagner (2013) but based on issue classification scheme of Stoll (2011), https://homepage.univie.ac.at/markus.wagner/Meyer_Wagner_CPS_suppmat.pdf"
label var niche_party_previous "Niche party program at t-1 (Formula after Meyer and Wagner (2013) but based on issue classification scheme of Stoll (2011), https://homepage.univie.ac.at/markus.wagner/Meyer_Wagner_CPS_suppmat.pdf"
label var niche_party "Niche party program at t (Formula after Meyer and Wagner (2013) but based on issue classification scheme of Stoll (2011), https://homepage.univie.ac.at/markus.wagner/Meyer_Wagner_CPS_suppmat.pdf"
label var vote_loss "Vote loss between t-1 and t-2 (data from Parlgov.org)"
label var vote_share "Vote share obtained in election t (Parlgov.org)"
label var party_age "Party age (based on party founding data from Parlgov.org)"
label var opposition "Opposition/government status resulting from election t (Parlgov.org)"
label var lopposition "Opposition/government status resulting from  election t-1 (based on data from Parlgov.org)"
label var leaderdom "Dominance of party leadership (Giger and Schumacher 2015)" 
label var inalliance "In alliance t (Parlgov.org)"
label var linalliance "In alliance t-1 (based on data from Parlgov.org)"
label var advantager "Advantage ratio resulting from election t (based on data from Parlgov.org)"
label var lr_extremity  "Extremity of left-right position t (based on Rile score of Comparative Manifesto Project"
label var norepres "No parliamentary representation gained in election t-1 (based on data from Parlgov.org plus additional data collected by author)"
label var norepres2 "No parliamentary representation gained in election t (based on data from Parlgov.org plus additional data collected by author)"
label var office_exp "Experience in government including result of election t (based on data from Parlgov.org)"
label var alliance_exp "Alliance experience including result of election t (based on data from Parlgov.org)"
label var totparlparties "Total number of parliamentary parties resulting from election t (based on data from Parlgov.org)"
label var merger "Party merges after election t (based on data from Parlgov.org plus additional data collected by own research assistant)"
label var reg_cost "Registration costs t (Tavits 2006)"
label var party_fin "Party financing t (Tavits 2006)"
label var ln_petit "Petition (logged) t (Tavits 2006)"
label var decade "Decade of election"
label var elec_year_parl2 "Last election observed in the dataset by country"

***Description of additional variables used for analyses presented in supplementary appendix
label var pss_mod3 "Party system saturation t (Based on residuals from Model 3, Table 2 of van de Wardt(2017)"
label var pss_cg "Party system saturation t (based on residuals from Table 2, Model established democracies of Clark and Golder (2006)"
label var cdiv "Cultural fractionalization t (Fearon 2003)"
label var LogMedian "Logged Median District Magnitude t (Carey and Hix 2011 with own additions for recent elections)"
label var nicheness_bischof "Nicheness of party program t (Bischof 2017)"
label var nicheness_meymil "Nicheness of party program t (Formula after Meyer & Miller (2013) but based on issue classification scheme of Stoll (2011))"
label var niche_party_previous_meymill "Niche party program at t-1 (1 if party was one sd above the mean score of its competitors on nicheness_meymil at t-1)"
label var niche_party_previous_bischof "Niche party program at t-1 (1 if party was one sd above the mean score of its competitors on nicheness_bischof at t-1)"
label var nicheness_previous "Nicheness compared to competitors' programs at t-1"
label var morecohesiveshiftdummy "Shift towards clearer platform (Lo et al 2016)"
label var niche_party_meguid "Niche party t (based on party family data from Parlgov.org)"
label var enep "Effective number of electoral parties t (Bormann and Golder 2013, Version 2.0)"


tsset party_id index

***Replicate Table 1 & Figure 3 (Nicheness hypothesis)

xtmixed nicheness c.l.pss##i.niche_party_previous vote_loss l.vote_share party_age lopposition i.decade || party_id:, var
est store mod1

margins, dydx(L.pss) at(niche_party_previous=(0 1)) l(95)
mplotoffset,  ///
ytitle("Marg. effect of party system saturation t-1") ///
xtitle("") ///
title("") ///
scheme(Tufte) ///
ci1opts(color(gs1) lwidth(medthick) msize(medlarge)) ///
plot1opts(lcolor(none) msymbol(D) mcolor(black) msize(large)) ///
yline(0, lcolor(black)) ///
allx ///
graphregion(fcolor(white)) name(a, replace) 

xtmixed nicheness c.l.pss##i.niche_party_previous##c.party_age  vote_loss l.vote_share lopposition i.decade ||  party_id:, var
est store mod2

margins, dydx(L.pss) at(niche_party_previous=(0 1) party_age=(1 25 50 75)) l(95)
mplotoffset, xtitle("") ///
 ytitle("Marg. effect of party sys. saturation t-1") title("")  ///
scheme(Tufte) ///
plot1opts(lcolor(none) msymbol(D) msize(large) mcolor(black)) ///
plot2opts(lcolor(none) msymbol(D) msize(large) mcolor(gs4)) ///
plot3opts(lcolor(none) msymbol(D) msize(large) mcolor(gs8)) ///
plot4opts(lcolor(none) msymbol(D) msize(large) mcolor(gs13))  ///
ci1opts(color(black) lwidth(medthick) msize(medlarge)) ///
ci2opts(color(gs4) lwidth(medthick) msize(medlarge)) ///
ci3opts(color(gs8) lwidth(medthick) msize(medlarge)) ///
ci4opts(color(gs13) lwidth(medthick) msize(medlarge)) ///
yline(0, lcolor(black)) ///
allx ///
legend(order(5 "Age=1" 6 "Age=25" 7 "Age=50" 8 "Age=75")) ///
graphregion(fcolor(white)) name(b, replace) 

xtmixed nicheness c.l.pss##i.niche_party_previous##c.leaderdom  vote_loss l.vote_share party_age lopposition i.decade ||  party_id:, var
est store mod3

margins, dydx(L.pss) at(niche_party_previous=(0 1) leaderdom=(0 10 20 30)) l(95)
mplotoffset, xtitle("") ///
 ytitle("Marg. effect of party sys. saturation t-1") title("")  ///
scheme(Tufte) ///
plot1opts(lcolor(none) msymbol(D) msize(large) mcolor(black)) ///
plot2opts(lcolor(none) msymbol(D) msize(large) mcolor(gs4)) ///
plot3opts(lcolor(none) msymbol(D) msize(large) mcolor(gs8)) ///
plot4opts(lcolor(none) msymbol(D) msize(large) mcolor(gs13))  ///
ci1opts(color(black) lwidth(medthick) msize(medlarge)) ///
ci2opts(color(gs4) lwidth(medthick) msize(medlarge)) ///
ci3opts(color(gs8) lwidth(medthick) msize(medlarge)) ///
ci4opts(color(gs13) lwidth(medthick) msize(medlarge)) ///
yline(0, lcolor(black)) ///
allx ///
legend(order(5 "Lead. dom.=0" 6 "Lead. dom.=10" 7 "Lead. dom.=20" 8 "Lead. dom.=30")) ///
graphregion(fcolor(white)) name(c, replace) 

xtmixed nicheness c.l.pss##i.niche_party_previous##c.l.vote_share  vote_loss party_age lopposition i.decade ||  party_id:, var
est store mod4

margins, dydx(L.pss) at(niche_party_previous=(0 1) L.vote_share=(0 10 30 50)) l(95)
mplotoffset, xtitle("") ///
 ytitle("Marg. effect of party sys. saturation t-1") title("")  ///
scheme(Tufte) ///
plot1opts(lcolor(none) msymbol(D) msize(large) mcolor(black)) ///
plot2opts(lcolor(none) msymbol(D) msize(large) mcolor(gs4)) ///
plot3opts(lcolor(none) msymbol(D) msize(large) mcolor(gs8)) ///
plot4opts(lcolor(none) msymbol(D) msize(large) mcolor(gs13))  ///
ci1opts(color(black) lwidth(medthick) msize(medlarge)) ///
ci2opts(color(gs4) lwidth(medthick) msize(medlarge)) ///
ci3opts(color(gs8) lwidth(medthick) msize(medlarge)) ///
ci4opts(color(gs13) lwidth(medthick) msize(medlarge)) ///
yline(0, lcolor(black)) ///
allx ///
legend(order(5 "Size t-1=0" 6 "Size t-1=10" 7 "Size t-1=30" 8 "Size t-1=50")) ///
graphregion(fcolor(white)) name(d, replace) 

xtmixed nicheness c.l.pss##i.niche_party_previous##i.lopposition vote_loss party_age l.vote_share i.decade || party_id:, var
est store mod5

margins, dydx(L.pss) at(niche_party_previous=(0 1) lopposition=(0 1)) l(95)
mplotoffset, xtitle("") ///
 ytitle("Marg. effect of party sys. saturation t-1") title("")  ///
scheme(Tufte) ///
plot1opts(lcolor(none) msymbol(D) msize(large) mcolor(black)) ///
plot2opts(lcolor(none) msymbol(D) msize(large) mcolor(gs13)) ///
ci1opts(color(black) lwidth(medthick) msize(medlarge)) ///
ci2opts(color(gs13) lwidth(medthick) msize(medlarge)) ///
yline(0, lcolor(black)) ///
allx ///
legend(order(3 "Government t-1" 4 "Opposition t-1")) ///
graphregion(fcolor(white)) name(e, replace) 

graph combine a b c d e, altshrink graphregion(fcolor(white)) 
capture graph export "YOUR LOCATION/Figure3.wmf", replace
capture esttab  mod1 mod2 mod3 mod4 mod5,  stats(r2 bic N)  starlevels(* 0.1 ** 0.05 *** 0.01) b(3) se(3) , using "YOUR LOCATION/Table1.csv", replace


***Replicate Table 2 & Figure 4 (Alliance hypothesis)

xtmelogit inalliance l.pss norepres lopposition l.office_exp l.alliance_exp l.totparlparties party_age  if linalliance==1   || ccode:, var
est store mod1

xtmelogit inalliance l.pss l.advantager norepres lopposition l.office_exp  l.alliance_exp l.totparlparties l.lr_extremity party_age  if linalliance==0 || ccode:, var
est store mod2

xtmelogit inalliance c.l.pss##c.party_age l.advantager norepres lopposition l.office_exp  l.alliance_exp l.totparlparties l.lr_extremity  if linalliance==0  || ccode:, var
est store mod3

margins, dydx(L.pss) at(party_age=(0(1)181)) l(95)

gen xyz=1 if e(sample)==1
matrix y_=r(table)'
svmat y_
range g 0 181 182

twoway hist party_age if xyz==1, percent bcolor(gs15) yaxis(2)  ///
|| line y_5 y_6 g,  lcolor(black) lpattern(dash dash)  ///
|| line y_1 g, lcolor(black) ///
|| line yline g, lcolor(black) ///
,  xtitle("Party age",  size(medsmall)) ///
yscale(alt) yscale(alt axis(2)) ///
ytitle("% of observations", size(medsmall) axis(2)) ///
ytitle("Marg. effect of party system saturation t-1", size(medsmall) axis(1)) ///
legend(off)  graphregion(color(white)) name(a, replace)

drop xyz- g

xtmelogit inalliance c.l.pss##c.leaderdom l.advantager norepres lopposition l.office_exp  l.alliance_exp l.totparlparties l.lr_extremity party_age if linalliance==0  || ccode:, var 
est store mod4

margins, dydx(L.pss) at(leaderdom=(0(1)30)) l(95)

gen xyz=1 if e(sample)==1
matrix y_=r(table)'
svmat y_
range g 0 30 31

twoway hist leaderdom if xyz==1, percent bcolor(gs15) yaxis(2)  ///
|| line y_5 y_6 g,  lcolor(black) lpattern(dash dash)  ///
|| line y_1 g, lcolor(black) ///
|| line yline g, lcolor(black) ///
,  xtitle("Leader dominance",  size(medsmall)) ///
yscale(alt) yscale(alt axis(2)) ///
ytitle("% of observations", size(medsmall) axis(2)) ///
ytitle("Marg. effect of party system saturation t-1", size(medsmall) axis(1)) ///
legend(off)  graphregion(color(white)) name(b, replace)

drop xyz- g

xtmelogit inalliance c.l.pss##c.l.vote_share l.advantager norepres lopposition l.office_exp  l.alliance_exp l.totparlparties l.lr_extremity party_age if linalliance==0  || ccode:, var
est store mod5

margins, dydx(L.pss) at(L.vote_share=(0(1)60)) l(95)

gen xyz=1 if e(sample)==1
matrix y_=r(table)'
svmat y_
range g 0 60 61

gen lsize=l.vote_share
twoway hist lsize if xyz==1, percent bcolor(gs15) yaxis(2)  ///
|| line y_5 y_6 g,  lcolor(black) lpattern(dash dash)  ///
|| line y_1 g, lcolor(black) ///
|| line yline g, lcolor(black) ///
,  xtitle("Party size t-1",  size(medsmall)) ///
yscale(alt) yscale(alt axis(2)) ///
ytitle("% of observations", size(medsmall) axis(2)) ///
ytitle("Marg. effect of party system saturation t-1", size(medsmall) axis(1)) ///
legend(off)  graphregion(color(white)) name(c, replace)

drop xyz- g

xtmelogit inalliance c.l.pss##i.lopposition l.advantager norepres  l.office_exp  l.alliance_exp l.totparlparties l.lr_extremity party_age  if linalliance==0  || ccode:, var
est store mod6

margins, dydx(L.pss) at(lopposition=(0 1)) l(95)
mplotoffset,  ///
ytitle("Marg. effect of party system saturation t-1") ///
xtitle("") ///
title("") ///
scheme(Tufte) ///
ci1opts(color(gs1) lwidth(medthick) msize(medlarge)) ///
plot1opts(lcolor(none) msymbol(D) mcolor(black) msize(large)) ///
yline(0, lcolor(black)) ///
allx ///
graphregion(fcolor(white)) name(d, replace) 

graph combine a b c d , altshrink graphregion(fcolor(white)) 
capture graph export "YOUR LOCATION\Figure4.wmf", replace
capture esttab mod1 mod2 mod3 mod4 mod5 mod6 ,  stats(pr2 bic N)  starlevels(* 0.1 ** 0.05 *** 0.01) b(3) se(3) , using "YOUR LOCATION\Table2.csv", replace


***Replicate Table 3 & Figure 5 (Merger hypothesis)

preserve

drop if elec_year==elec_year_parl2

firthlogit merger pss party_age advantager norepres2 opposition office_exp alliance_exp lr_extremity reg_cost party_fin ln_petit
tab merger if e(sample)==1
est store mod1
firthfit

firthlogit merger pss party_age norepres2 opposition office_exp alliance_exp 
tab merger if e(sample)==1
est store mod2
firthfit

firthlogit merger c.pss##c.party_age norepres2 opposition office_exp alliance_exp 
tab merger if e(sample)==1
est store mod3
firthfit
margins, dydx(pss) at(party_age=(0(1)181)) l(95)

gen xyz=1 if e(sample)==1
matrix y_=r(table)'
svmat y_
range g 0 181 182

twoway hist party_age if xyz==1, percent bcolor(gs15) yaxis(2)  ///
|| line y_5 y_6 g,  lcolor(black) lpattern(dash dash)  ///
|| line y_1 g, lcolor(black) ///
|| line yline g, lcolor(black) ///
,  xtitle("Party age",  size(medsmall)) ///
yscale(alt) yscale(alt axis(2)) ///
ytitle("% of observations", size(medsmall) axis(2)) ///
ytitle("Marg. effect of party system saturation", size(medsmall) axis(1)) ///
legend(off)  graphregion(color(white)) name(a, replace)

drop xyz- g


firthlogit merger c.pss##c.vote_share party_age norepres2 opposition office_exp alliance_exp 
tab merger if e(sample)==1
est store mod4
firthfit

margins, dydx(pss) at(vote_share=(0(1)60)) l(95)

gen xyz=1 if e(sample)==1
matrix y_=r(table)'
svmat y_
range g 0 60 61

twoway hist vote_share if xyz==1, percent bcolor(gs15) yaxis(2)  ///
|| line y_5 y_6 g,  lcolor(black) lpattern(dash dash)  ///
|| line y_1 g, lcolor(black) ///
|| line yline g, lcolor(black) ///
,  xtitle("Party size",  size(medsmall)) ///
yscale(alt) yscale(alt axis(2)) ///
ytitle("% of observations", size(medsmall) axis(2)) ///
ytitle("Marg. effect of party system saturation", size(medsmall) axis(1)) ///
legend(off)  graphregion(color(white)) name(b, replace)

drop xyz- g

firthlogit merger c.pss##i.opposition party_age norepres2 office_exp alliance_exp 
tab merger if e(sample)==1
est store mod5
firthfit

margins, dydx(pss) at(opposition=(0 1)) l(95)
mplotoffset,  ///
ytitle("Marg. effect of party system saturation") ///
xtitle("") ///
title("") ///
scheme(Tufte) ///
ci1opts(color(gs1) lwidth(medthick) msize(medlarge)) ///
plot1opts(lcolor(none) msymbol(D) mcolor(black) msize(large)) ///
yline(0, lcolor(black)) ///
allx ///
graphregion(fcolor(white)) name(c, replace) 

graph combine a b c, altshrink graphregion(fcolor(white)) 
capture graph export "YOUR LOCATION\Figure5.wmf", replace
capture esttab mod1 mod2 mod3 mod4 mod5 ,  stats(pr2 bic N)  starlevels(* 0.1 ** 0.05 *** 0.01) b(3) se(3) , using "YOUR LOCATION\Table3.csv", replace

restore

log close

